package com.socket.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.socket.core.util.Wss;
import com.socket.secure.util.Assert;
import com.socket.server.custom.exception.BizException;
import com.socket.server.mapper.SysGroupMapper;
import com.socket.server.mapper.SysProessMapper;
import com.socket.server.model.base.BasePo;
import com.socket.server.model.enmus.ProessState;
import com.socket.server.model.po.SysGroup;
import com.socket.server.model.po.SysProess;
import com.socket.server.service.SysProessService;
import com.socket.server.util.ShiroUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysProessServiceImpl extends ServiceImpl<SysProessMapper, SysProess> implements SysProessService {
    private final SysGroupMapper groupMapper;

    @Override
    public boolean apply(String guid, String target, String reason) {
        LambdaQueryWrapper<SysProess> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysProess::getGuid, guid);
        wrapper.eq(SysProess::getTarget, target);
        wrapper.orderByDesc(BasePo::getCreateTime);
        SysProess first = getFirst(wrapper);
        if (first != null) {
            boolean untreat = ProessState.UNTREAT.getCode() == first.getState();
            Assert.isFalse(untreat, "您已经发送过申请", BizException::new);
            boolean resolve = ProessState.RESOLVE.getCode() == first.getState();
            boolean group = Wss.isGroup(target);
            Assert.isFalse(resolve, group ? "您已经是群组成员" : "对方已经是您的好友", BizException::new);
        }
        // 保存申请关系
        SysProess proess = new SysProess();
        proess.setGuid(guid);
        proess.setTarget(target);
        proess.setState(ProessState.UNTREAT.getCode());
        proess.setReason(reason);
        return super.save(proess);
    }

    @Override
    public List<SysProess> applyList() {
        String userId = ShiroUser.getUserId();
        LambdaQueryWrapper<SysProess> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysProess::getState, ProessState.UNTREAT.getCode());
        // 审批群组 先获取当前用户作为所有者的群组列表
        LambdaQueryWrapper<SysGroup> wrapper1 = Wrappers.lambdaQuery();
        wrapper1.eq(SysGroup::getOwner, userId);
        List<String> targets = groupMapper.selectList(wrapper1)
                .stream()
                .map(SysGroup::getGuid)
                .collect(Collectors.toList());
        // 目标添加自己
        targets.add(userId);
        wrapper.in(SysProess::getTarget, targets);
        return list(wrapper);
    }

    @Override
    public boolean state(String approver, String target, ProessState state) {
        // 参数校验
        Assert.notNull(state, NullPointerException::new);
        Assert.isTrue(state != ProessState.UNTREAT, "你不能将记录设置为待处理", BizException::new);
        // 设置申请关系
        LambdaUpdateWrapper<SysProess> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(SysProess::getTarget, approver);
        wrapper.eq(SysProess::getGuid, target);
        wrapper.set(SysProess::getState, state.getCode());
        return super.update(wrapper);
    }

    @Override
    public List<SysProess> userList() {
        LambdaQueryWrapper<SysProess> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysProess::getGuid, ShiroUser.getUserId());
        wrapper.eq(SysProess::getState, ProessState.RESOLVE.getCode());
        return list(wrapper);
    }

    @Override
    public boolean delete(String guid, String target) {
        LambdaUpdateWrapper<SysProess> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(SysProess::getGuid, guid);
        wrapper.eq(SysProess::getTarget, target);
        wrapper.set(SysProess::isDeleted, 1);
        return update(wrapper);
    }

    @Override
    public List<String> groupGuids(String gid) {
        LambdaQueryWrapper<SysProess> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(SysProess::getTarget, gid);
        wrapper.eq(SysProess::getState, ProessState.RESOLVE.getCode());
        return list(wrapper).stream().map(SysProess::getGuid).collect(Collectors.toList());
    }
}
